﻿using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using Microsoft.Phone.Controls;
using Newtonsoft.Json;
using WhallaToolkit.ShareServices.Exceptions;
using WhallaToolkit.ShareServices.Helpers;
using WhallaToolkit.ShareServices.Models;
using WhallaToolkit.ShareServices.Models.AccessTokens;
using WhallaToolkit.ShareServices.Services;
using TweetSharp;
using WhallaToolkit.IsolatedStorage;

namespace WhallaToolkit.ShareServices.Brokers
{
    public sealed class TwitterAuthenticationBroker
    {
        #region Fields

        private static OAuthRequestToken RequestToken;
        private static string responseData = "";
        private static uint responseErrorDetail = 0;
        private static WebAuthenticationStatus responseStatus = WebAuthenticationStatus.UserCancel;
        private static readonly AutoResetEvent authenticateFinishedEvent = new AutoResetEvent(false);
        private static readonly IIsolatedStorageService isolatedStorageRepository = new IsolatedStorageService();
        #endregion


        #region Properties

       internal static  bool AuthenticationInProgress { get;  set; }
        internal static  Uri StartUri { get;  set; }
        internal static Uri EndUri { get; set; }
        internal static string TokenVerifier { get; set; } 

        #endregion


        #region Methods
        
        static async Task<TwitterAccessToken> AuthenticateAsync()
        {
            TwitterAccessToken returnToken = null;
            var rootFrame = Application.Current.RootVisual as PhoneApplicationFrame;
            if (rootFrame == null)
            {
                throw new InvalidOperationException();
            }

            TwitterService service = new TwitterService();
            RequestToken = await service.GetRequestTokenAsync(PortalsResources.TwitterConsumerKey, PortalsResources.TwitterConsumerSecret);
            var uri = service.GetAuthorizationUri(RequestToken);

            TwitterAuthenticationBroker.StartUri = TwitterServices.GetLoginUrl(RequestToken);
            TwitterAuthenticationBroker.EndUri = new Uri("http://whallalabs.com/metroweather/twitter/success", UriKind.RelativeOrAbsolute); ;
            TwitterAuthenticationBroker.AuthenticationInProgress = true;

            // Navigate to the login page.
            rootFrame.Navigate(new Uri("/SocialService;component/Brokers/Twitter/TwitterConnect.xaml", UriKind.RelativeOrAbsolute));


            Task<WebAuthenticationResult> task = Task<WebAuthenticationResult>.Factory.StartNew(() =>
            {
                authenticateFinishedEvent.WaitOne();
                return new WebAuthenticationResult(responseData, responseStatus, responseErrorDetail);
            });

            WebAuthenticationResult result = await task;
            OAuthAccessToken accessToken = null;

            if (result.ResponseStatus == WebAuthenticationStatus.Success)
            {
                accessToken = await service.GetAccessTokenAsync(PortalsResources.TwitterConsumerKey, PortalsResources.TwitterConsumerSecret, RequestToken, TokenVerifier);
            }
            else if (result.ResponseStatus == WebAuthenticationStatus.UserCancel)
            {
                throw new UserCanceledAuthenticationException();
            }
            else if (result.ResponseStatus == WebAuthenticationStatus.ErrorHttp)
            {
                throw new HttpErrorAuthenticationException();
            }
            if (accessToken != null)
            {
                returnToken = new TwitterAccessToken(accessToken);
                isolatedStorageRepository.SaveSettings("social_twitter_tokens", JsonConvert.SerializeObject(returnToken));
            }
            return returnToken;

        }

        public static async Task<TwitterAccessToken> AuthenticateTwitterAsync()
        {
            string serializedToken = isolatedStorageRepository.LoadSettings<string>("social_twitter_tokens");

            if (serializedToken == null)
            {
                return await AuthenticateAsync();
            }
            TwitterAccessToken twitterAccessToken =JsonConvert.DeserializeObject<TwitterAccessToken>(serializedToken);
            return twitterAccessToken;
        }

        internal static void OnAuthenticationFinished(string data, WebAuthenticationStatus status, uint error, string tokenVerifier)
        {
            TwitterAuthenticationBroker.TokenVerifier = tokenVerifier;
            TwitterAuthenticationBroker.responseData = data;
            TwitterAuthenticationBroker.responseStatus = status;
            TwitterAuthenticationBroker.responseErrorDetail = error;

            TwitterAuthenticationBroker.AuthenticationInProgress = false;

            // Signal the waiting task that the authentication operation has finished.
            authenticateFinishedEvent.Set();
        } 

        #endregion

    }
}
